package com.lbw.Client.serviceCenter;


import com.lbw.Client.cache.serviceCache;
import com.lbw.Client.serviceCenter.balance.impl.ConsistencyHashBalance;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import com.lbw.Client.serviceCenter.ZkWatcher.watchZK;
import java.net.InetSocketAddress;
import java.util.List;

/**
 * @author lbwxxc
 * @date 2025/2/20 15:15
 * @description: 负责连接zk，并从ck获得数据
 */
public class ZKServiceCenter implements ServiceCenter{
    // curator 提供的zookeeper客户端
    private CuratorFramework client;
    //zookeeper根路径节点
    private static final String ROOT_PATH = "MyRPC";
    private static final String RETRY = "CanRetry";
    private serviceCache cache;

    public ZKServiceCenter() throws InterruptedException {
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
        this.client = CuratorFrameworkFactory.builder().connectString("127.0.0.1:2181")
                .sessionTimeoutMs(4000).retryPolicy(retryPolicy).namespace(ROOT_PATH).build();
        this.client.start();
        System.out.println("zookeeper 连接成功");
        cache = new serviceCache();
        watchZK watcher = new watchZK(client, cache);
        watcher.watchToUpdate(ROOT_PATH);

    }
    @Override
    public InetSocketAddress serviceDiscovery(String serviceName) {
        try {
            List<String> strings = cache.getServiceFromCache(serviceName);
            if (strings == null || strings.isEmpty()) {
                strings =  client.getChildren().forPath("/" + serviceName);
            }
            // 负载均衡
            String string = new ConsistencyHashBalance().balance(strings);
            return this.parseAddress(string);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public boolean checkRetry(String serviceName) {
        boolean canRetry = false;
        try {
            List<String> serviceList = client.getChildren().forPath("/" + RETRY);
            for (String address : serviceList) {
                if (address.equals(serviceName)) {
                    System.out.println("服务"+serviceName+"在白名单上，可进行重试");
                    canRetry=true;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return canRetry;
    }

    /**
     * @param: serverAddress
     * @return: java.lang.String
     * @description: // 地址 -> XXX.XXX.XXX.XXX:port 字符串
     */
    private String getServiceAddress(InetSocketAddress serverAddress) {
        return serverAddress.getHostName() + ":" + serverAddress.getPort();
    }

    private InetSocketAddress parseAddress(String address) {
        String[] split = address.split(":");
        return new InetSocketAddress(split[0], Integer.parseInt(split[1]));
    }

}
